/**
 * @file JSONWriter.h
 */
#ifndef _JSONWRITER_H_
#define _JSONWRITER_H_

#include "../common/BaseObject.h"
#include "../text/CFString.h"
#include "../io/Writer.h"
#include "../lang/Primitive.h"
#include "../collections/StackT.h"
#include "../collections/ArrayT.h"
#include "../collections/HashtableT.h"
#include "../util/BitAttributeT.h"

namespace cppflib
{

namespace json
{

/**
 *  A class to write JSON text to a provided writer
 */
class _DLLAPI JSONWriter : public BaseObject
{
private:
    bool indent;
    bool closeOutputWriter;
    util::BitAttributeT<enumforward_t> *pWriterState;
    collections::StackWChar *pObjArrayStack;
    collections::StackCppObjT<collections::HashtableT<CFString, lang::Boolean> > *pObjectNameStack;
    collections::ArrayWChar *pTempCharBuf;
    io::Writer *pOutputWriter;

private:
	JSONWriter(void);
    void WriteNewline(bool forceWrite = false);
    void WriteIndentSpaces(bool isEndObjArray = false);
    void WriteComma();
    void WriteStringValue(pcwstr_t str, int offset, int count);

public:
	JSONWriter(io::Writer *pOutputWriter, bool isIndent, bool closeOutputWriter);
	virtual ~JSONWriter(void);

    void Close();
    void Flush();

    JSONWriter & Object();
    JSONWriter & EndObject();
    JSONWriter & Array();
    JSONWriter & EndArray();

    JSONWriter & Key(const CFString &key);
    JSONWriter & Value(const CFString &value);
    JSONWriter & Value(const CFString &value, int offset, int count);
    JSONWriter & Value(collections::ArrayWChar &value);
    JSONWriter & Value(collections::ArrayWChar &value, int offset, int count);
    JSONWriter & Value(bool v);
    JSONWriter & Value(double v);
    JSONWriter & Value(int v);
    JSONWriter & Value(i64_t v);
    JSONWriter & ValueNull();

    JSONWriter & Comment(const CFString &comment);

    void EndDocument();
};

} // end of namespace json

} // end of namespace cppflib


#endif
